home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / UTIL / Folder・Icon・Opener 1.0.1.sit / Folder•Icon•Opener 1.0.1 / source code / sources / FIOpen.file.c < prev    next >
Text File  |  1996-05-05  |  11KB  |  382 lines

  1. /*
  2.  *--------------------------------------------------------------
  3.  * FIOpen.file.c
  4.  *--------------------------------------------------------------
  5.  *    Copyright ゥ Fumio Rokkaku, 1996
  6.  *--------------------------------------------------------------
  7.  */
  8. #pragma once
  9.  
  10. /* System Headers */
  11. #include <Memory.h>
  12. #include <Files.h>
  13. #include <Folders.h>
  14. #include <Finder.h>
  15. #include <Aliases.h>
  16. #include <Resources.h>
  17. #include <OSUtils.h>
  18. #include <Processes.h>
  19. #include <icons.h>
  20. #include <Errors.h>
  21.  
  22. /* Project Headers */
  23. #include "FIOpen.h"
  24.  
  25. /*
  26.  *--------------------------------------------------------------
  27.  *    resource ID and type constant to determine the icon editor
  28.  *    application
  29.  *--------------------------------------------------------------
  30.  */
  31. enum {
  32.     kDataBaseID = 128
  33. };
  34. enum {
  35.     rFolderType    = 'FLDR',
  36.     rEditorType    = 'EDTR'
  37. };
  38. /*
  39.  *--------------------------------------------------------------
  40.  * 'STR#' ID and index in the Finder which designates
  41.  *    the hidden custom icon file name
  42.  *--------------------------------------------------------------
  43.  */
  44. enum {
  45.     kIconStrID    = 11250,
  46.     kIconStrIdx    = 5
  47. };
  48.  
  49. /*
  50.  *--------------------------------------------------------------
  51.  * static function prototypes
  52.  *--------------------------------------------------------------
  53.  */
  54. static OSErr FSpGetIconSpec(const FSSpecPtr, FSSpecPtr);
  55. static OSErr GetIconEditor(FSSpecPtr);
  56. static OSErr GetMyLocation(FSSpecPtr);
  57. static OSErr FindAppFromItsSig(const OSType, FSSpecPtr);
  58. static OSErr GetIconFileName(StringPtr);
  59.  
  60. /*
  61.  *--------------------------------------------------------------
  62.  * static global which specifiles the icon edotor
  63.  *--------------------------------------------------------------
  64.  */
  65. static FSSpec    gIconEditor;
  66. /*
  67.  *--------------------------------------------------------------
  68.  * SetUpMyEditor
  69.  *--------------------------------------------------------------
  70.  *    prepare the icon editor spec 
  71.  *--------------------------------------------------------------
  72.  */
  73. Boolean SetUpMyEditor(void)
  74. {
  75.     OSErr    result = GetIconEditor(&gIconEditor);
  76.     if (result != noErr) {
  77.         NoEditorAlert();
  78.     }
  79.     return (result == noErr);
  80. }
  81. /*
  82.  *--------------------------------------------------------------
  83.  * OpenFolderIcon
  84.  *--------------------------------------------------------------
  85.  *    Get a "Icon" file in the given folder spec and pass it to
  86.  *    ResEdit
  87.  *--------------------------------------------------------------
  88.  */
  89. OSErr OpenFolderIcon(FSSpecPtr theHFSSpec)
  90. {
  91.     FSSpec    iconSpec;
  92.     Boolean    isFolder, wasAlias;
  93.     OSErr    result;
  94.  
  95.     result = ResolveAliasFile(theHFSSpec, true, &isFolder, &wasAlias);
  96.     if (result == noErr) {
  97.         if (isFolder) {
  98.             if (IsKeyPressed(kCommandKey)) {
  99.                 /* just copy icon suite to clipboard */
  100.                 result = GetIconToScrap(theHFSSpec);
  101.             } else {
  102.                 /* open a icon file using the certain app */
  103.                 result = FSpGetIconSpec(theHFSSpec, &iconSpec);
  104.                 if (result == noErr) {
  105.                     result = PassFileToApp(&gIconEditor, &iconSpec);
  106.                 }
  107.             }
  108.         } else {
  109.             /* just pass the file */
  110.             result = PassFileToApp(&gIconEditor, theHFSSpec);
  111.         }
  112.     }
  113.     return (result);
  114. }
  115. /*
  116.  *--------------------------------------------------------------
  117.  * FSpGetIconSpec
  118.  *--------------------------------------------------------------
  119.  *    make an Icon File spec in the Folder
  120.  *--------------------------------------------------------------
  121.  */
  122. static OSErr FSpGetIconSpec(const FSSpecPtr theFolder, FSSpecPtr theIconSpec)
  123. {
  124.     CInfoPBRec aPB;
  125.     Str63    tempName;
  126.     OSErr    result;
  127.  
  128.     /* Protection against File Sharing problem */
  129.     if ((theFolder->name == nil) || (theFolder->name[0] == 0)) {
  130.         tempName[0] = 0;
  131.         aPB.hFileInfo.ioNamePtr = tempName;
  132.         aPB.hFileInfo.ioFDirIndex = -1;    /* use ioDirID only */
  133.     } else {
  134.         aPB.hFileInfo.ioNamePtr = theFolder->name;
  135.         aPB.hFileInfo.ioFDirIndex = 0;    /* use ioNamePtr and ioDirID */
  136.     }
  137.     aPB.hFileInfo.ioCompletion = nil;
  138.     aPB.hFileInfo.ioVRefNum    = theFolder->vRefNum;
  139.     aPB.hFileInfo.ioDirID    = theFolder->parID;
  140.     result = PBGetCatInfoSync(&aPB);
  141.  
  142.     if (result == noErr) {
  143.         if ((aPB.dirInfo.ioFlAttrib & ioDirMask) == 0) {
  144.             NoFolderAlert(theFolder->name);
  145.             return (dirNFErr);
  146.         }
  147.         /* make a hidde icon file spec */
  148.         result = GetIconFileName(tempName);
  149.         if (result == noErr) {
  150.             result = FSMakeFSSpec(
  151.                 theFolder->vRefNum, aPB.dirInfo.ioDrDirID, tempName, theIconSpec
  152.             );
  153.         }
  154.         if (result == noErr) {
  155.             /* set custom icon bit for safety */
  156.             aPB.dirInfo.ioDrUsrWds.frFlags |= kHasCustomIcon;
  157.         } else {
  158.             /* reset custom icon bit for safety */
  159.             aPB.dirInfo.ioDrUsrWds.frFlags &= ~kHasCustomIcon;
  160.         }
  161.         aPB.hFileInfo.ioCompletion = nil;
  162.         aPB.hFileInfo.ioVRefNum    = theFolder->vRefNum;
  163.         aPB.hFileInfo.ioDirID    = theFolder->parID;
  164.         result = PBSetCatInfoSync(&aPB);
  165.     }
  166.     if (result != noErr) {
  167.         NoIconAlert(theFolder->name);
  168.     }
  169.     return (result);
  170. }
  171. /*
  172.  *--------------------------------------------------------------
  173.  * GetIconEditor
  174.  *--------------------------------------------------------------
  175.  *    get an icon editor spec by a couple of search methods
  176.  *--------------------------------------------------------------
  177.  */
  178. static OSErr GetIconEditor(FSSpecPtr theAppSpec)
  179. {
  180.     Handle    aDataHandle = nil;
  181.     Str63    aName;
  182.     FSSpec    mySpec, folderSpec;
  183.     OSErr    result;
  184.  
  185.     /* get a folder name from a database resource */
  186.     aDataHandle = Get1Resource(rFolderType, kDataBaseID);
  187.     if (aDataHandle != nil) {
  188.         HLock(aDataHandle);
  189.         PStrCpy((StringPtr)*aDataHandle, aName);
  190.         HUnlock(aDataHandle);
  191.         ReleaseResource(aDataHandle);
  192.     } else {
  193.         result = resNotFound;
  194.     }
  195.     /* find a folder which contains icon editor application */
  196.     if (result == noErr) {
  197.         result = GetMyLocation(&mySpec);
  198.     }
  199.     if (result == noErr) {
  200.         result = FSMakeFSSpec(mySpec.vRefNum, mySpec.parID, aName, &folderSpec);
  201.         if (result != noErr) {
  202.             long    folderID;
  203.             FSpDirCreate(&folderSpec, smRoman, &folderID);
  204.         }
  205.     }
  206.     /* find an editor application */
  207.     if (result == noErr) {
  208.         CInfoPBRec    aPB;
  209.  
  210.         /* get a folder's info */
  211.         aPB.dirInfo.ioNamePtr = folderSpec.name;
  212.         aPB.dirInfo.ioVRefNum = folderSpec.vRefNum;
  213.         aPB.dirInfo.ioDrDirID = folderSpec.parID;
  214.         aPB.dirInfo.ioFDirIndex = 0;
  215.         result = PBGetCatInfoSync((CInfoPBPtr)&aPB);
  216.         if (result == noErr) {
  217.             long    aDirID   = aPB.dirInfo.ioDrDirID;
  218.             short    aVRefNum = aPB.dirInfo.ioVRefNum;
  219.             short    idx = 1;
  220.             /* search files in the folder */
  221.             do {
  222.                 aName[0] = 0;
  223.                 aPB.hFileInfo.ioNamePtr = aName;
  224.                 aPB.hFileInfo.ioVRefNum = aVRefNum;
  225.                 aPB.hFileInfo.ioDirID   = aDirID;
  226.                 aPB.hFileInfo.ioFDirIndex = idx++;
  227.                 result = PBGetCatInfoSync((CInfoPBPtr)&aPB);
  228.                 if (result == noErr) {
  229.                     result = FSMakeFSSpec(aVRefNum, aDirID, aName, theAppSpec);
  230.                 }
  231.                 if (result == noErr) {
  232.                     Boolean    isFolder, wasAlias;
  233.                     result = ResolveAliasFile(theAppSpec, true, &isFolder, &wasAlias);
  234.                 }
  235.                 if (result == noErr) {
  236.                     FInfo    appsInfo;
  237.                     result = FSpGetFInfo(theAppSpec, &appsInfo);
  238.                     if (appsInfo.fdType == 'APPL') {
  239.                         /* break the loop */
  240.                         return (result);
  241.                     }
  242.                 }
  243.             } while (result == noErr);
  244.         }
  245.     }
  246.     if (result != noErr) {
  247.         aDataHandle = Get1Resource(rEditorType, kDataBaseID);
  248.         if (aDataHandle != nil) {
  249.             OSType aCreator = **((OSType **)aDataHandle);
  250.             ReleaseResource(aDataHandle);
  251.  
  252.             /* find the application from its signature */
  253.             result = FindAppFromItsSig(aCreator, theAppSpec);
  254.         }
  255.     }
  256.     return (result);
  257. }
  258. /*
  259.  *--------------------------------------------------------------
  260.  * GetMyLocation
  261.  *--------------------------------------------------------------
  262.  *    get FSSpec if myself
  263.  *--------------------------------------------------------------
  264.  */
  265. static OSErr GetMyLocation(FSSpecPtr theSpec)
  266. {
  267.     ProcessSerialNumber    myPSN;
  268.     OSErr        result;
  269.  
  270.     result = GetCurrentProcess(&myPSN);
  271.     if (result == noErr) {
  272.         ProcessInfoRec    myInfo;
  273.         Str63    processName;
  274.         myInfo.processName = processName;
  275.         myInfo.processAppSpec = theSpec;
  276.         result = GetProcessInformation(&myPSN, &myInfo);
  277.     }
  278.     return (result);
  279. }
  280. /*--------------------------------------------------------------
  281.  * FindAppFromItsSig
  282.  *--------------------------------------------------------------
  283.  *    find a process from the application's signature
  284.  *--------------------------------------------------------------
  285.  */
  286. static OSErr FindAppFromItsSig(const OSType theSig, FSSpecPtr theSpec)
  287. {
  288.     DTPBRec            aDTPBRec;
  289.     DTPBPtr            aDBP;
  290.     VolumeParam        *aVLP;
  291.     HFileParam        *aFIP;
  292.     Str63    itsName;
  293.     short    volIndex;
  294.     OSErr    result;
  295.  
  296.     /* substitute pointers */
  297.     aDBP = &aDTPBRec;
  298.     aVLP = (VolumeParam *)aDBP;
  299.     aFIP = (HFileParam    *)aDBP;
  300.  
  301.     /* search the application */
  302.     volIndex = 0;
  303.     do {
  304.         /* get a volume info */
  305.         itsName[0] = 0;
  306.         aVLP->ioCompletion = nil;
  307.         aVLP->ioVolIndex = ++volIndex;
  308.         aVLP->ioNamePtr = itsName;
  309.         result = PBGetVInfoSync((ParmBlkPtr)aVLP);
  310.  
  311.         /* get a desktop file path */
  312.         if (result == noErr) {
  313.             result = PBDTGetPath(aDBP);
  314.         }
  315.  
  316.         /* get an application info of the volume */
  317.         if (result == noErr) {
  318.             itsName[0] = 0;
  319.             aDBP->ioNamePtr = itsName;
  320.             aDBP->ioIndex = 0;
  321.             aDBP->ioFileCreator = theSig;
  322.             result = PBDTGetAPPLSync(aDBP);
  323.         }
  324.  
  325.         /* confirm the result */
  326.         if (result == noErr) {
  327.             /* once copy answers */
  328.             theSpec->vRefNum = aDBP->ioVRefNum;
  329.             theSpec->parID = aDBP->ioAPPLParID;
  330.             BlockMove(itsName, theSpec->name, *itsName +1);
  331.  
  332.             aFIP->ioFVersNum = 0;
  333.             aFIP->ioFDirIndex = 0;
  334.             aFIP->ioVRefNum    = theSpec->vRefNum;
  335.             aFIP->ioDirID     = theSpec->parID;
  336.             result = PBHGetFInfoSync((HParmBlkPtr)aFIP);
  337.         }
  338.         if (result == noErr) {
  339.             if (aFIP->ioFlFndrInfo.fdType != 'APPL') {
  340.                 result = afpItemNotFound;
  341.             }
  342.         }
  343.         if (result == noErr) {
  344.             return noErr;
  345.         }
  346.     } while (result != nsvErr);    /* until no such volume */
  347.     return (result);
  348. }
  349. /*
  350.  *--------------------------------------------------------------
  351.  * GetIconFileName
  352.  *--------------------------------------------------------------
  353.  *    get a file name of the hidden custom icon file
  354.  *    From Finder resource
  355.  *--------------------------------------------------------------
  356.  */
  357. static OSErr GetIconFileName(StringPtr theName)
  358. {
  359.     FSSpec    finderSpec;
  360.     short    finderRef;
  361.     OSErr    result;
  362.  
  363.     result = FindFolder(kOnSystemDisk, kSystemFolderType,
  364.                 kDontCreateFolder, &finderSpec.vRefNum, &finderSpec.parID);
  365.     if (result == noErr) {
  366.         result = FSMakeFSSpec(finderSpec.vRefNum, finderSpec.parID,
  367.                 "¥pFinder", &finderSpec);
  368.     }
  369.     if (result == noErr) {
  370.         SetResLoad(false);
  371.         finderRef = FSpOpenResFile(&finderSpec, fsRdPerm);
  372.         result = ResError();
  373.         SetResLoad(true);
  374.     }
  375.     if (result == noErr) {
  376.         UseResFile(finderRef);
  377.         GetIndString(theName, kIconStrID, kIconStrIdx);
  378.         CloseResFile(finderRef);
  379.     }
  380.     return (result);
  381. }
  382.